package worker

import (
	"gitee.com/zhengjianfeng/crontab-worker/common"
	"math/rand"
	"os/exec"
	"time"
)

var (
	// 单例
	G_executor *Executor
)

// 执行任务
type Executor struct{}

// 执行一个任务
func (executor *Executor) ExecuteWorkerJob(info *common.WorkerJobExecuteInfo, workerJobPlan *common.WorkerJobSchedulerPlan) {
	go func() {
		var (
			result        *common.WorkerJobExecuteResult
			cmd           *exec.Cmd
			output        []byte
			err           error
			workerJobLock *WorkerJoblock
		)
		//TODO info.WorkerJob.JobType  不同的类型 使用不同的解析器解析和执行不同的工作

		// 任务结果
		result = &common.WorkerJobExecuteResult{
			WorkerJobSchedulerPlan: workerJobPlan,
			WorkerJobExecuteInfo:   info,
			JobBatch:               info.JobBatch,
			Output:                 make([]byte, 0),
		}

		// 首先获取分布式锁
		// 初始化分布式锁
		workerJobLock = G_workerJobMgr.CreateWorkerJobLock(workerJobPlan.JobBatch)

		// 记录任务开始时间
		result.StartTime = time.Now()

		// 随机睡眠（0～1秒） TODO
		time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)

		// 上锁
		err = workerJobLock.TryLock()

		// 释放锁
		//defer workerJobLock.UnLock()

		if err != nil {
			//fmt.Println(err.Error())
			// 上锁失败
			result.Err = err
			result.EndTime = time.Now()
		} else {
			go func() {
				time.Sleep(4 * time.Second)
				workerJobLock.UnLock()
			}()
			//time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond)
			//fmt.Println("抢锁成功")
			// 上锁成功后重置任务开始时间
			result.StartTime = time.Now()

			//time.Sleep(1000 * time.Millisecond)

			// 执行任务
			cmd = exec.CommandContext(info.CancelCtx, "/bin/bash", "-c", info.WorkerJob.Command)

			// 执行并捕获输出
			output, err = cmd.CombinedOutput()

			// 记录任务的结束时间
			result.EndTime = time.Now()

			result.Output = output
			result.Err = err
		}

		// 任务执行完成后，把结果返回给Scheduler, Scheduler会从executingTable中删除执行记录
		G_scheduler.PushJobResult(result)
	}()
}

// 初始化执行器
func InitExecutor() (err error) {
	G_executor = &Executor{}
	return
}
